package stat

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"navi-mumbai/common/gensql"
	"time"
)

var _ UserLoginLogModel = (*customUserLoginLogModel)(nil)

type (
	// UserLoginLogModel is an interface to be customized, add more methods here,
	// and implement the added methods in customUserLoginLogModel.
	UserLoginLogModel interface {
		userLoginLogModel
		InsertOrUpdate(ctx context.Context, id, loginDate, uid, channel int64) (sql.Result, error)
		CountLoginUser(ctx context.Context, start, end *time.Time, startUid, endUid int64) (int64, error)
	}

	customUserLoginLogModel struct {
		*defaultUserLoginLogModel
		genSql *gensql.GenSql
	}
)

// NewUserLoginLogModel returns a model for the database table.
func NewUserLoginLogModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UserLoginLogModel {
	return &customUserLoginLogModel{
		defaultUserLoginLogModel: newUserLoginLogModel(conn, c, opts...),
		genSql:                   gensql.NewGenSql(),
	}
}

func (m *customUserLoginLogModel) InsertOrUpdate(ctx context.Context, id, loginDate, uid, channel int64) (sql.Result, error) {
	query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?) ON CONFLICT (id) DO UPDATE SET login_cnt = %s.login_cnt + 1", m.table, userLoginLogRowsExpectAutoSet, m.table)
	ret, err := m.ExecNoCacheCtx(ctx, query, id, uid, loginDate, 1, channel)
	return ret, err
}

func (m *customUserLoginLogModel) CountLoginUser(ctx context.Context, start, end *time.Time, startUid, endUid int64) (int64, error) {
	query := fmt.Sprintf("select count(id) from %s ", m.table)
	m.genSql.InitSql(query)

	if start != nil {
		m.genSql = m.genSql.Where("create_time >= ?", start)
	}
	if end != nil {
		m.genSql = m.genSql.Where("create_time <= ?", end)
	}
	if startUid != 0 {
		m.genSql = m.genSql.Where("uid >= ?", startUid)
	}
	if endUid != 0 {
		m.genSql = m.genSql.Where("uid <= ?", endUid)
	}

	q, v, err := m.genSql.ToSql()
	if err != nil {
		return 0, err
	}

	var resp int64
	err = m.QueryRowNoCacheCtx(ctx, &resp, q, v...)
	switch err {
	case nil:
		return resp, nil
	default:
		return 0, err
	}
}
